﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Grain.Crm.DataMigrator.CrmServices;
using Grain.Crm.ExcelExtractor.Input;
using Grain.Crm.ExcelProcessor;

namespace Grain.Crm.DataMigrator.Infrastructure
{
    public class SheetImportProcess
    {
        public ImportEntityTask[] ImportTasks { get; set; }
        public SheetDescription[] SheetDescriptions { get; set; }
        public SheetEntityMapping[] EntitySheetMappings { get; set; }

        protected ICrmService Service { get; set; }

       
        public void Build(ICrmService service, string filePath)
        {
            Service = service;
            var sharedContainer = new Container();

            foreach(var task in ImportTasks)
            {
                EnumerableRowCollection<DataRow> data;
                var sheet = GetSheetDescription(task.EntityName);

                XlsProcessor.QueryData(filePath, sheet.SheetName, out data);

                var contentRetriever = new SheetContentRetriever(GetSheetDescription(task.EntityName), task.EntityName,
                                                                 data);
                var content = contentRetriever.Retrieve();

                var builder = new Builder(content.HeaderRow, content.ContentRow, Service, sharedContainer);

                task.Build(builder);
            }
        }

        public void Execute()
        {
            foreach (var task in ImportTasks)
                task.Execute();
        }

        private SheetDescription GetSheetDescription(string entityName)
        {
            var sheetDescriptionMapping = this.EntitySheetMappings.SingleOrDefault(m => m.EntityName == entityName);
            if(sheetDescriptionMapping == null)
                throw new InvalidOperationException("Sheet description for entity not found in mappings. Entity:" +
                                                    entityName);

            var desc = this.SheetDescriptions.SingleOrDefault(s => s.SheetName == sheetDescriptionMapping.SheetName);

            if (desc == null)
                throw new InvalidOperationException("Sheet description for entity not found. Sheet description name:" +
                                                    sheetDescriptionMapping.SheetName + ". Entity:" + sheetDescriptionMapping.EntityName);
            return desc;
           
        }
    }
    public class SheetEntityMapping
    {
        public string SheetName { get; set; }
        public string EntityName { get; set; }
    }
}
